/**
 * goio-bean
 * 
 * This class do
 * 
 * @link http://www.marcosperon.com/
 * @copyright 2009 - Peron Co.
 * @author Marcos Peron
 * @package com.marcosperon.dao
 * @version 2009
 */
package com.mperon.dao;

import com.mperon.util.config.SimpleConfig;

/**
 * The Class DAOFactory.
 * 
 * @author marcos
 */
public class DAOFactory {

    /** The Constant DAO_FACTORY_CONFIG_CREATOR. */
    private static final String DAO_FACTORY_CONFIG_CREATOR = "factory.creator";

    /** The Constant factory. */
    private static final DAOFactory factory = new DAOFactory();

    /** The creator. */
    private DAOCreator creator;

    /**
     * Instantiates a new dAO factory.
     */
    public DAOFactory() {
    }

    /**
     * Instantiates a new dAO factory.
     * 
     * @param c
     *            the c
     */
    public DAOFactory(final DAOCreator c) {
        configure(c);
    }

    /**
     * Gets the single instance of DAOFactory.
     * 
     * @return single instance of DAOFactory
     */
    public static DAOFactory getInstance() {
        return factory;
    }

    /**
     * Gets the dAO.
     * 
     * @param claz
     *            the claz
     * 
     * @return the dAO
     */
    public <T extends DAO<?>> T getDAO(final Class<?> claz) {
        if (creator == null) {
            throw new InvalidCreatorException("The creator is not found or is invalid!");
        }
        @SuppressWarnings("unchecked")
        final T obj = (T)creator.getDAO(claz);
        if (obj == null) {
            throw new DAONotFoundException("The DAO for " + claz.toString() + " was not found");
        }
        return obj;
    }

    /**
     * Configure.
     * 
     * @param c
     *            the c
     * 
     * @return the dAO factory
     */
    public DAOFactory configure(final DAOCreator c) {
        if (c == null) {
            throw new InvalidCreatorException("The creator is not found or is invalid!");
        }
        creator = c;
        return this;
    }

    /**
     * Configure.
     * 
     * @param cfg
     *            the cfg
     * 
     * @return the dAO factory
     */
    public DAOFactory configure(final SimpleConfig cfg) {
        final DAOCreator c = (DAOCreator)cfg.getInstance(DAO_FACTORY_CONFIG_CREATOR);
        configure(c);
        return this;
    }
}
